/*
 * @Description: 代码生成基础数据
 * @Author: DHL
 * @Date: 2022-01-29 15:14:02
 * @LastEditors: DHL
 * @LastEditTime: 2022-12-12 10:04:40
 */

import { stringUtils } from '/@/utils/stringUtils'

/**
 * 查询方式
 */
export const queryWay = ['=', '!=', '>', '>=', '<', '<=', 'like', 'between']

/**
 * 组件类型
 */
export const componentType = [
  {
    code: 'input',
    name: '文本框',
    javaType: ['String', 'byte[]']
  },
  {
    code: 'textarea',
    name: '文本域'
  },
  {
    code: 'select',
    name: '下拉框'
  },
  {
    code: 'inputNumber',
    name: '数字',
    javaType: ['int', 'Long', 'Integer', 'BigInteger', 'Float', 'Double', 'BigDecimal']
  },
  {
    code: 'radio',
    name: '单选框'
  },
  {
    code: 'checkbox',
    name: '复选框'
  },
  {
    code: 'datePicker',
    name: '日期',
    javaType: ['LocalDate']
  },
  {
    code: 'dateTimePicker',
    name: '日期时间',
    javaType: ['LocalDateTime']
  },
  {
    code: 'timePicker',
    name: '时间选择器'
  },
  {
    code: 'timeSelect',
    name: '时间选择'
  },
  {
    code: 'switch',
    name: '开关',
    javaType: ['Boolean']
  },
  {
    code: 'upload',
    name: '上传组件'
  },
  {
    code: 'dataDic',
    name: '数据字典组件'
  },
  {
    code: 'money',
    name: '金额组件'
  }
]

/**
 * mysql 物理类型对应 java类型
 */
export const mysqlToJavaType = {
  bigint: 'Long',
  tinyint: 'Byte',
  smallint: 'Short',
  mediumint: 'Integer',
  integer: 'Integer',
  int: 'Integer',
  float: 'Float',
  double: 'Double',
  decimal: 'BigDecimal',
  numeric: 'BigDecimal',
  char: 'String',
  varchar: 'String',
  tinyblob: 'byte[]',
  tinytext: 'String',
  blob: 'byte[]',
  text: 'String',
  mediumblob: 'byte[]',
  mediumtext: 'String',
  longblob: 'byte[]',
  longtext: 'String',
  date: 'LocalDate',
  time: 'LocalDate',
  year: 'LocalDate',
  datetime: 'LocalDateTime',
  timestamp: 'LocalDateTime'
}

/**
 * mysql 物理类型对应 JDBC类型
 */
export const mysqlToJdbcType = {
  bigint: 'BIGINT',
  tinyint: 'TINYINT',
  smallint: 'SMALLINT',
  mediumint: 'INTEGER',
  integer: 'INTEGER',
  int: 'INTEGER',
  float: 'REAL',
  double: 'DOUBLE',
  decimal: 'DECIMAL',
  numeric: 'DECIMAL',
  char: 'CHAR',
  varchar: 'VARCHAR',
  tinyblob: 'BINARY',
  tinytext: 'VARCHAR',
  blob: 'BINARY',
  text: 'LONGVARCHAR',
  mediumblob: 'LONGVARBINARY',
  mediumtext: 'LONGVARCHAR',
  longblob: 'LONGVARBINARY',
  longtext: 'LONGVARCHAR',
  date: 'DATE',
  time: 'TIME',
  year: 'DATE',
  datetime: 'TIMESTAMP',
  timestamp: 'TIMESTAMP'
}

/**
 * java数据类型转typescript类型
 */
export const javaToTs = {
  String: 'string',
  'byte[]': 'string',
  int: 'number',
  Long: 'number',
  Integer: 'number',
  Boolean: 'boolean',
  BigInteger: 'number',
  Float: 'number',
  Double: 'number',
  BigDecimal: 'number',
  LocalDate: 'string',
  LocalDateTime: 'string'
}

/**
 * 获取javaType下拉选项
 * @returns
 */
export function getJavaTypeSelect() {
  let javaType: Array<string> = []
  for (const [key, val] of Object.entries(mysqlToJavaType)) {
    if (!javaType.includes(val)) {
      javaType.push(val)
    }
  }
  return javaType
}

/**
 * 获取javaType
 */
/**
 * 获取JavaType
 * @param column 列对象
 */
function getJavaType(column: any) {
  let javaType = ''
  for (const [key, val] of Object.entries(mysqlToJavaType)) {
    if (column.dataType.toLowerCase() === key.toLowerCase()) {
      javaType = val
    }
  }
  column.javaType = javaType
}

/**
 * 获取jdbcType
 */
export function getJdbcType(dataType: string) {
  let jdbcType = ''
  for (const [key, val] of Object.entries(mysqlToJdbcType)) {
    if (dataType.toLowerCase() === key.toLowerCase()) {
      jdbcType = val
    }
  }
  return jdbcType
}

/**
 * 获取typescript类型
 */
export function getTsType(dataType: string) {
  let tsType = ''
  for (const [key, val] of Object.entries(javaToTs)) {
    if (dataType.toLowerCase() === key.toLowerCase()) {
      tsType = val
    }
  }
  return tsType
}

/**
 * 获取java字段
 * @param columnName
 */
function getJavaField(column: any) {
  column.columnName = column.columnName.toLowerCase()
  column.javaField = column.columnName.replace(/_(\w)/g, function (all: any, letter: any) {
    return letter.toUpperCase()
  })

  if (column.javaField.charAt(column.javaField.length - 1) === '_') {
    column.javaField = column.javaField.substr(0, column.javaField.length - 1)
  }
}

/**
 * 获取选中状态
 * @param action 操作
 * @param column 列名称
 */
function getCheckbox(action: string, column: any) {
  // 表单排除字段
  const excludeForm = [
    'ISDEL',
    'CREATOR_ID',
    'CREATOR',
    'CREATE_DATE',
    'UPDATER_ID',
    'UPDATER',
    'UPDATE_DATE',
    'CREATOR_ORGID',
    'VERSION',
    'TENANT_ID'
  ]

  // 必填排除字段
  const excludeRequired = [
    'ID',
    'ISDEL',
    'CREATOR_ID',
    'CREATOR',
    'CREATE_DATE',
    'UPDATER_ID',
    'UPDATER',
    'UPDATE_DATE',
    'CREATOR_ORGID',
    'VERSION',
    'TENANT_ID'
  ]

  // Java Bean 排除字段
  const excludeJavaBean = [
    'ISDEL',
    'CREATOR_ID',
    'CREATOR',
    'CREATE_DATE',
    'UPDATER_ID',
    'UPDATER',
    'UPDATE_DATE',
    'CREATOR_ORGID',
    'TENANT_ID'
  ]

  // 列表排除字段
  const excludeList = [
    'ID',
    'ISDEL',
    'CREATOR_ID',
    'UPDATER_ID',
    'VERSION',
    'TENANT_ID',
    'CREATOR_ORGID'
  ]

  // 查询条件排除字段
  const excludeQuery: Array<string> = [
    'ISDEL',
    'CREATOR_ID',
    'UPDATER_ID',
    'VERSION',
    'TENANT_ID',
    'CREATOR_ORGID'
  ]

  switch (action) {
    case 'javaBean':
      column.javaBean = !excludeJavaBean.includes(column.columnName.toUpperCase())
      break

    case 'form':
      column.form = !excludeForm.includes(column.columnName.toUpperCase())
      break

    case 'list':
      column.list = !excludeList.includes(column.columnName.toUpperCase())
      break

    case 'query':
      column.query = !excludeQuery.includes(column.columnName.toUpperCase())
      break

    case 'required':
      column.required = !excludeRequired.includes(column.columnName.toUpperCase())
      break

    default:
      break
  }
}

/**
 * 获取查询方式
 * @param column
 */
function getQueryWay(column: any) {
  let rtn = '='
  switch (column.javaType) {
    case 'String':
      rtn = 'like'
      break
    default:
      rtn = '='
      break
  }

  if (stringUtils.isNotEmpty(column.columnKey) || stringUtils.isNotEmpty(column.dataDic)) {
    rtn = '='
  }

  // 查询方式是 【=】
  const equalArray = ['ISDEL', 'CREATOR_ID', 'UPDATER_ID', 'CREATOR_ORGID', 'VERSION', 'TENANT_ID']
  if (equalArray.includes(column.columnName.toUpperCase())) {
    rtn = '='
  }

  column.queryWay = rtn
}

/**
 * 获取组件类型
 * @param column
 */
function getComponentType(column: any) {
  let _componentType = 'input'
  componentType.forEach((item) => {
    if (item.javaType?.includes(column.javaType)) {
      _componentType = item.code
    }
  })

  if (stringUtils.isNotEmpty(column.dataDic)) {
    _componentType = 'dataDic'
  }
  column.componentType = _componentType
}

/**
 * 获取java信息
 * @param columnData
 * @param columnName  数据字典改变传参
 */
export function getJavaInfo(columnData: Array<any>, columnName?: string) {
  columnData.forEach((item) => {
    if (stringUtils.isNotEmpty(columnName) && item.columnName !== columnName) {
      return
    }

    item.javaComment = item.columnComment

    getJavaType(item)
    getJavaField(item)

    getQueryWay(item)
    getComponentType(item)

    getCheckbox('javaBean', item)
    getCheckbox('form', item)
    getCheckbox('list', item)
    getCheckbox('query', item)
    getCheckbox('required', item)
  })
}

/**
 * vue字段默认值
 * @param item
 * @returns
 */
export function getVueDefaultValue(column: any) {
  let rtn: any = `''`

  const tsType = getTsType(column.javaType)

  switch (tsType) {
    case 'number':
      rtn = `0`
      break

    case 'boolean':
      rtn = `true`
      break

    // case 'Date':
    //   rtn = `new Date()`
    //   break

    default:
      break
  }

  if (column.componentType === 'dataDic') {
    rtn = `''`
  }

  return rtn
}

/**
 * 获取类名
 * @param tableNames
 */
export function getClassName(tableNames: Array<string>, delPrefix: string) {
  let className = ''
  tableNames.forEach((item) => {
    if (stringUtils.isNotEmpty(delPrefix)) {
      item = item.substring(delPrefix.length, item.length)
    }
    className += item
      .replace(/_(\w)/g, function (all, letter) {
        return letter.toUpperCase()
      })
      .replace(/^\S/, (s) => s.toUpperCase())
  })
  return className
}

/**
 * 首字母大学
 * @param str
 * @returns
 */
export function firstToUpperCase(str: string) {
  return str.replace(/^\S/, (s) => s.toUpperCase())
}

/**
 * 首字母小写
 * @param str
 * @returns
 */
export function firstToLowerCase(str: string) {
  return str.replace(/^\S/, (s) => s.toLowerCase())
}

/**
 * 菜单 list 转 tree
 */
export function menuListToTree(menuList: Array<any>, parentId: string) {
  // 资源菜单集合
  let menuTree: any = []

  for (const menu of menuList) {
    const { id, text, pid, resType } = menu as any

    let menuItem: any = {
      id: id,
      label: text,
      children: []
    }

    const _parentResId = pid ? pid : ''
    if (parentId === _parentResId) {
      // 递归
      const menuChildren = menuListToTree(menuList, id)

      if (menuChildren && menuChildren.length > 0) {
        menuItem.children = menuChildren
      }

      menuTree.push(menuItem)
    }
  }

  return menuTree
}

/**
 * 获取权限KEY
 * @param prefix
 * @param type
 */
export function getAuthKey(prefix: string, type: string) {
  const authKey: any = {
    list: `${prefix}-LIST`,
    add: `${prefix}-ADD`,
    edit: `${prefix}-EDIT`,
    view: `${prefix}-VIEW`,
    delBatch: `${prefix}-DEL-BATCH`,
    delLogicBatch: `${prefix}-DEL-LOGIC-BATCH`,
    exportExcel: `${prefix}-EXPORTEXCEL`
  }
  return authKey[type]
}
